//
// Created by Administrator on 2017/8/4.
//

#ifndef AUTOMAHJONG_PRT_H
#define AUTOMAHJONG_PRT_H

namespace utils {
    template<class T>
    class Prt {
    public:
        Prt();

        Prt(T *obj);

        Prt(const Prt<T> &obj);

        ~Prt();

        Prt<T> &operator=(const Prt<T> &obj);

        T operator=(const T value);

        T *operator->();

        bool isNull();

    private:
        T *mObj;
        int *mCount;
    };

    template<class T>
    Prt<T>::Prt() {
        mCount = nullptr;
        mObj = nullptr;
    }

    template<class T>
    Prt<T>::Prt(T *obj) {
        if (obj) {
            mCount = new int();
            *mCount = 1;
            mObj = obj;
        }
    }

    template<class T>
    Prt<T>::Prt(const Prt<T> &obj) {
        if (mCount = obj.mCount)
            (*mCount)++;
        mObj = obj.mObj;
    }

    template<class T>
    Prt<T>::~Prt() {
        if (mCount) {
            (*mCount)--;
            if (0 == *mCount) {
                delete mCount;
                delete mObj;
            }
        }
    }

    template<class T>
    Prt<T> &Prt<T>::operator=(const Prt<T> &obj) {
        if (mCount) {
            (*mCount)--;
            if (0 == *mCount) {
                delete mCount;
                delete mObj;
            }
        }
        if (mCount = obj.mCount)
            (*mCount)++;
        mObj = obj.mObj;
        return *this;
    }

    template<class T>
    T Prt<T>::operator=(const T value) {
        *mObj = value;
        return *mObj;
    }

    template<class T>
    T *Prt<T>::operator->() {
        return mObj;
    }

    template<class T>
    bool Prt<T>::isNull() {
        return !mObj;
    }
}

#endif //AUTOMAHJONG_PRT_H
